package com.shitou.springai1.user.service;

import com.shitou.springai1.admin.entity.dto.ImageDto;
import com.shitou.springai1.user.entity.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class EnhancedChatService {

    @Autowired
    private ChatClient chatClient;

    @Autowired
    private EnhancedImageSearchService enhancedImageSearchService;

    @Autowired
    private ConversationMemoryService memoryService;

    @Value("classpath:promapt/system-promapt.st")
    private Resource systemPromptResource;

    /**
     * 增强的流式聊天 - 集成图片搜索和对话记忆
     */
    public Flux<StreamResponseMessage> enhancedStreamChat(ConversationRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE);

        return Flux.create(emitter -> {
            try {
                String question = request.getQuestion();
                String sessionId = request.getSessionId();

                log.info("开始处理增强流式聊天: session={}, question={}", sessionId, question);

                // 1. 获取对话历史
                String conversationHistory = memoryService.getConversationSummary(sessionId);
                log.info("对话历史内容: {}", conversationHistory);

                // 2. 先进行图片搜索
                EnhancedSearchResult searchResult = enhancedImageSearchService.enhancedSearch(question);
                log.info("图片搜索结果: {}", searchResult);

                // 3. 发送意图和图片信息
                sendSearchResults(emitter, searchResult, sessionId);

                // 4. 构建包含上下文和图片信息的AI提示词
                Message systemMessage = buildContextAwareSystemMessage(question, searchResult, conversationHistory);
                System.out.println("系统消息内容: " + systemMessage);
                Message userMessage = new UserMessage(question);
                Prompt prompt = new Prompt(List.of(systemMessage, userMessage));

                // 5. 流式生成AI回复
                generateStreamingResponse(emitter, prompt, searchResult, sessionId, question);

            } catch (Exception e) {
                log.error("增强流式聊天处理失败", e);
                emitter.next(new StreamResponseMessage(
                        MessageType.ERROR,
                        "处理失败: " + e.getMessage(),
                        null,
                        LocalDateTime.now()
                ));
                emitter.complete();
            }
        });
    }

    /**
     * 构建包含上下文和图片信息的系统消息
     */
    private Message buildContextAwareSystemMessage(String question, EnhancedSearchResult searchResult, String conversationHistory) {
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPromptResource);

        Map<String, Object> variables = new HashMap<>();
        variables.put("name", "小凯");
        variables.put("voice", "幽默的专业风格");

        // 构建完整的上下文
        String context = buildCompleteContext(searchResult, conversationHistory,question);
        variables.put("completeContext", context);

        return systemPromptTemplate.createMessage(variables);
    }

    /**
     * 构建完整的上下文信息
     */
    private String buildCompleteContext(EnhancedSearchResult searchResult, String conversationHistory,String question) {
        StringBuilder context = new StringBuilder();
        System.out.println("得到的图片信息: " + searchResult.getSearchResults());
        System.out.println("用户提的问题是： " + question);

        // 添加对话历史
        if (!conversationHistory.isEmpty()) {
            context.append(conversationHistory).append("\n\n");
        }
        // 添加图片搜索信息
        if (searchResult != null && !searchResult.getSearchResults().isEmpty()) {
            context.append("当前查询的相关信息：\n\n");

            for (int i = 0; i < Math.min(searchResult.getSearchResults().size(), 3); i++) {
                ImageDto image = searchResult.getSearchResults().get(i);
                context.append(String.format("%d. 【%s】%s\n",
                        i + 1, image.getImagesName(), image.getDescription()));
            }

            context.append("\n请优先基于以上准确信息进行回复。");
        } else if (conversationHistory.isEmpty()) {
            context.append("这是第一次对话，请友好地自我介绍并提供帮助。");
        }

        return context.toString();
    }

    /**
     * 生成流式文本响应
     */
    private void generateStreamingResponse(FluxSink<StreamResponseMessage> emitter,
                                           Prompt prompt,
                                           EnhancedSearchResult searchResult,
                                           String sessionId,
                                           String question) {

        StringBuilder aiResponseContent = new StringBuilder();

        // 使用AI生成流式回复
        chatClient.prompt(prompt).stream()
                .content()
                .doOnNext(textChunk -> {
                    aiResponseContent.append(textChunk);
                    // 发送文本流片段
                    emitter.next(new StreamResponseMessage(
                            MessageType.TEXT_CHUNK,
                            textChunk,
                            null,
                            LocalDateTime.now()
                    ));
                })
                .doOnComplete(() -> {
                    // 保存对话记录到记忆
                    saveConversationToMemory(sessionId, question, aiResponseContent.toString());

                    // 流结束，发送完成信号
                    emitter.next(new StreamResponseMessage(
                            MessageType.COMPLETE,
                            "流式响应完成",
                            Map.of(
                                    "totalImages", searchResult.getSearchResults().size(),
                                    "sessionId", sessionId,
                                    "turnsInMemory", memoryService.getOrCreateMemory(sessionId).getHistory().size()
                            ),
                            LocalDateTime.now()
                    ));
                    emitter.complete();
                    log.info("流式聊天处理完成, session={}", sessionId);
                })
                .doOnError(error -> {
                    log.error("AI流式生成失败", error);
                    emitter.next(new StreamResponseMessage(
                            MessageType.ERROR,
                            "AI生成失败: " + error.getMessage(),
                            null,
                            LocalDateTime.now()
                    ));
                    emitter.complete();
                })
                .subscribe();
    }

    /**
     * 保存对话到记忆
     */
    private void saveConversationToMemory(String sessionId, String userQuestion, String aiResponse) {
        try {
            memoryService.addConversationTurn(sessionId, "user", userQuestion);
            memoryService.addConversationTurn(sessionId, "assistant", aiResponse);
            log.debug("对话已保存到记忆, session={}, 用户: {}, AI: {}",
                    sessionId, userQuestion.length(), aiResponse.length());
        } catch (Exception e) {
            log.error("保存对话记忆失败", e);
        }
    }

    /**
     * 发送搜索结果
     */
    private void sendSearchResults(FluxSink<StreamResponseMessage> emitter,
                                   EnhancedSearchResult searchResult,
                                   String sessionId) {
        // 发送会话信息
        ConversationMemory memory = memoryService.getOrCreateMemory(sessionId);
        Map<String, Object> sessionInfo = new HashMap<>();
        sessionInfo.put("sessionId", sessionId);
        sessionInfo.put("historyTurns", memory.getHistory().size());
        sessionInfo.put("isNewSession", memory.getHistory().isEmpty());

        emitter.next(new StreamResponseMessage(
                MessageType.INTENT_INFO,
                memory.getHistory().isEmpty() ? "新会话开始" : "继续现有对话",
                sessionInfo,
                LocalDateTime.now()
        ));

        // 发送图片数据（原有逻辑）
        if (!searchResult.getSearchResults().isEmpty()) {
            Map<String, Object> imageData = new HashMap<>();
            imageData.put("images", searchResult.getSearchResults());
            imageData.put("count", searchResult.getSearchResults().size());
            imageData.put("searchQuery", searchResult.getActualSearchQuery());

            emitter.next(new StreamResponseMessage(
                    MessageType.IMAGE_DATA,
                    String.format("找到 %d 张相关图片", searchResult.getSearchResults().size()),
                    imageData,
                    LocalDateTime.now()
            ));
        }
    }

    // ... 其他方法保持不变（createErrorMessage等）

    /**
     * 获取会话记忆信息
     */
    public Map<String, Object> getSessionInfo(String sessionId) {
        ConversationMemory memory = memoryService.getOrCreateMemory(sessionId);
        Map<String, Object> info = new HashMap<>();
        info.put("sessionId", sessionId);
        info.put("createdAt", memory.getCreatedAt());
        info.put("lastAccessed", memory.getLastAccessed());
        info.put("totalTurns", memory.getHistory().size());
        info.put("recentHistory", memory.getHistory().stream()
                .limit(5)
                .collect(Collectors.toList()));
        return info;
    }

    /**
     * 清除会话记忆
     */
    public void clearSessionMemory(String sessionId) {
        // 注意：这里不能直接remove，因为可能正在使用
        ConversationMemory memory = memoryService.getOrCreateMemory(sessionId);
        memory.getHistory().clear();
        log.info("已清除会话 {} 的记忆", sessionId);
    }
}
